<template>
  <el-dialog title="选择图片" :visible.sync="show" :close-on-click-modal="false" :show-close="!uploading" width="1170px" top="50px" append-to-body @closed="reset">
    <div class="loading" v-loading="uploading" element-loading-text="图片上传处理中" element-loading-background="rgba(255, 255, 255, 0.5)" v-if="uploading" />
    <div class="loading" v-loading="removeLoading" element-loading-text="图片删除处理中" element-loading-background="rgba(255, 255, 255, 0.5)" v-else-if="removeLoading" />
    <div class="loading" v-loading="listLoading" element-loading-text="加载中" element-loading-background="rgba(255, 255, 255, 0.5)" v-else-if="listLoading" />
    <el-form size="small" inline @submit.native.prevent v-if="scoreTypeList.length">
      <el-form-item label="选择类型">
        <el-select v-model="scoreType" placeholder="请选择类型" filterable :disabled="uploading" @change="getList">
          <el-option label="全部" :value="allTypeValue" style="font-size: 14px" />
          <div v-for="item in scoreTypeList" :key="item.value">
            <el-option-group :label="item.chkitemName" v-if="item.children && item.children.length">
              <el-option v-for="child in item.children" :key="child.chkitemCode" :label="child.chkitemName" :value="child.chkitemCode" style="font-size: 14px; padding-left: 30px" />
            </el-option-group>
            <el-option :label="item.chkitemName" :value="item.chkitemCode" style="font-size: 14px" v-else />
          </div>
        </el-select>
      </el-form-item>
      <el-form-item>
        <el-popover placement="top" trigger="hover" content="请选择类型" v-if="!scoreType">
          <el-button slot="reference" type="primary" icon="el-icon-upload">上传图片</el-button>
        </el-popover>
        <el-button type="primary" icon="el-icon-upload" @click="clickUpload" v-else>上传图片</el-button>
      </el-form-item>
    </el-form>

    <div class="upload-box">
      <el-upload
        ref="upload"
        :action="FILE_MULTI_UPLOAD_URL"
        :data="{ type: 'qcMoudle' }"
        name="files"
        multiple
        accept=".png,.jpg,.jpeg"
        list-type="picture-card"
        :file-list="fileList"
        :disabled="!taskId || !scoreType || uploading"
        :before-upload="beforeUpload"
        :on-error="onUploadError"
        :on-success="onUploadSuccess"
      >
        <i slot="default" class="el-icon-plus" ref="uploadBtn" />
        <div slot="file" slot-scope="{ file }" class="item" :class="{ checked: file.checked }" @click="toggleSelect(file)">
          <el-image class="el-upload-list__item-thumbnail g-img-placeholder" :src="file.url" fit="cover" />
          <span class="el-upload-list__item-actions actions">
            <span @click.stop="imgsPreview(file)">
              <i class="el-icon-zoom-in" />
            </span>
            <span @click.stop="handleRemove(file)">
              <i class="el-icon-delete" />
            </span>
          </span>
        </div>
      </el-upload>
    </div>

    <div slot="footer" class="footer-box">
      <el-pagination
        background
        layout="total, sizes, prev, pager, next"
        :page-sizes="[20, 30, 50, 100]"
        :total="taskFileList.length"
        :page-size.sync="pageSize"
        :current-page.sync="pageNum"
        @size-change="handlePaging"
        @current-change="handlePaging"
        v-show="taskFileList.length"
      />
      <div v-show="!taskFileList.length" />
      <div>
        <span class="text-selected" v-if="selected.length"> 已选择 {{ selected.length }} 张 </span>
        <el-button type="primary" :disabled="listLoading || !selected.length" @click="btnSubmit">确 定</el-button>
        <el-button :disabled="uploading" @click="show = false">取 消</el-button>
      </div>
    </div>

    <el-image ref="previewRef" class="hide" :src="previewSrc" :preview-src-list="previewSrcList" />
  </el-dialog>
</template>
<script>
// 根据抽检类型显示图片文件列表。支持多选
import { debounce } from '@/utils'
import { FILE_MULTI_UPLOAD_URL, getFileURL } from '@/api/common'
import { getTaskFileList, addRdcTaskFile, deleteRdcTaskFile } from '@/api/projectInspection/courseCheck'
import { listChkitem } from '@/api/checkScore/cqEval.js'
import { flatList2tree } from '@/utils'
const acceptTypeList = ['image/jpeg', 'image/png', 'image/jpg']
const uploadStatusList = ['ready', 'uploading']
export default {
  name: 'SelectFileList',
  props: {
    value: { type: Boolean, default: false },
    multiple: { type: Boolean, default: false }
  },
  data() {
    return {
      FILE_MULTI_UPLOAD_URL,
      show: false,
      processType: '',
      taskId: '',
      scoreType: '',
      uploading: false,
      removeLoading: false,
      listLoading: false,
      pageNum: 1,
      pageSize: 20,
      taskFileList: [],
      fileList: [],
      previewSrcList: [],
      previewSrc: '',
      scoreTypeList: [],
      allTypeValue: ''
    }
  },
  computed: {
    selected() {
      return this.fileList.filter(i => i.taskFileId && i.checked)
    }
  },
  watch: {
    uploading(val, oldVal) {
      // 批量上传结束
      if (!val && oldVal) this.getList()
    }
  },
  created() {
    this.btnSubmit = debounce(this.onSubmit, 1e3, true)
    this.initData = JSON.parse(JSON.stringify(this.$data))
    this.$route.query.chkitemCode
  },
  methods: {
    reset() {
      const data = JSON.parse(JSON.stringify(this.initData))
      Object.keys(data).map(k => (this[k] = data[k]))
    },
    open(item = {}) {
      const { taskId, scoreType } = item
      // if (!processType || !taskId) return this.msgError('无效参数')

      // this.processType = processType
      this.taskId = taskId
      this.scoreType = scoreType
      this.show = true
      this.getList()
      this.getListChkitem()
    },
    async getListChkitem() {
      const params = {
        versionCode: this.$route.query.versionCode,
        chkitemCode: this.$route.query.chkitemCode
      }
      // this.allTypeValue = params.chkitemCode
      if (!params.versionCode || !params.chkitemCode) return

      this.listLoading = true
      const res = await listChkitem(params).catch(() => false)
      this.listLoading = false
      if (res === false) return

      let data = res.data.filter(item => item.chkitemCode !== params.chkitemCode) || []
      data.map(i => {
        i.isEnableLoading = false
        i.removeLoading = false
      })
      data = flatList2tree(data, { id: 'chkitemId' })
      this.scoreTypeList = data
    },
    async getList() {
      const { taskId, scoreType } = this
      if (!taskId) return this.msgError('无效参数')

      const opt = { taskId, fileType: scoreType }
      this.listLoading = true
      const res = await getTaskFileList(opt).catch(() => false)
      this.listLoading = false
      if (res === false) {
        this.taskFileList = []
        return (this.fileList = [])
      }

      const data = res.data || []
      data.map(i => {
        i.checked = false
        i.url = getFileURL(i.fileId)
      })
      this.taskFileList = data

      this.pageNum = 1
      this.handlePaging()
    },
    handlePaging() {
      // 本地分页
      const { pageNum, pageSize } = this
      const offset = Math.max(0, pageNum - 1) * pageSize
      this.taskFileList.map(i => (i.checked = false))
      this.fileList = this.taskFileList.slice(offset, offset + pageSize)
    },
    async onSubmit() {
      const { selected } = this
      if (!selected.length) return this.msgInfo('请选择图片')

      const data = this.multiple ? selected : selected[0]
      this.show = false
      this.$emit('ok', data)
    },
    clickUpload() {
      this.$refs?.uploadBtn.click()
    },
    beforeUpload(file) {
      const isAccept = acceptTypeList.includes(file.type)
      const isLt10M = file.size / 1024 / 1024 < 10
      if (!isAccept) this.msgError('上传图片只能是 JPG/PNG 格式!')
      if (!isLt10M) this.msgError('上传图片大小不能超过 10MB!')

      const isOk = isAccept && isLt10M
      if (!this.uploading) this.uploading = isOk
      return isOk
    },
    finishUpload(fileList) {
      // 无上传中的项时关闭 loading
      if (!fileList.some(i => uploadStatusList.includes(i.status))) this.uploading = false
    },
    onUploadError(err, file, fileList) {
      this.finishUpload(fileList)
      this.msgError(`上传失败 ${err?.msg || ''}`)
    },
    async onUploadSuccess(res, file, fileList) {
      const { taskId, scoreType } = this
      if (res.code !== 200) {
        this.finishUpload(fileList)
        return this.msgError(`上传失败 ${res.msg || ''}`)
      }
      // 绑定到当前记录
      const opt = {
        taskId,
        fileType: scoreType,
        isFolder: 0,
        fileId: res.data[0],
        fileName: file.name
      }
      const res2 = await addRdcTaskFile(opt).catch(() => false)
      this.finishUpload(fileList)
      if (res2 === false) return this.msgError('添加图片失败')
    },
    imgsPreview(file) {
      this.previewSrcList = this.fileList.map(i => i.url)
      this.previewSrc = file.url
      this.$nextTick(() => this.$refs.previewRef?.clickHandler())
    },
    async handleRemove(file) {
      const res1 = await this.$confirm('确定删除此图片?', '警告', { type: 'warning' }).catch(() => false)
      if (res1 !== 'confirm') return

      const { taskFileId } = file
      this.removeLoading = true
      const res = await deleteRdcTaskFile({ taskFileId }).catch(() => false)
      this.removeLoading = false
      if (res === false) return

      // 从列表移除
      const index = this.taskFileList.findIndex(i => i.taskFileId === taskFileId)
      if (index > -1) this.taskFileList.splice(index, 1)
      // 从当前页移除
      const index2 = this.fileList.findIndex(i => i.taskFileId === taskFileId)
      if (index2 > -1) this.fileList.splice(index2, 1)
      this.msgSuccess('删除成功')

      // 回到第一页
      if (!this.fileList.length) {
        this.pageNum = 1
        this.handlePaging()
      }
    },
    toggleSelect(file) {
      const { taskFileId } = file
      if (!taskFileId) return this.msgInfo('未上传成功，不能操作')
      // if (file.status !== 'success') return this.msgInfo('未上传成功，不能操作')
      file.checked = !file.checked
      if (!this.multiple) this.fileList.map(i => i.taskFileId !== taskFileId && (i.checked = false))
    }
  }
}
</script>
<style lang="scss" scoped>
.loading {
  position: absolute;
  top: 0;
  left: 0;
  right: 0;
  bottom: 0;
  z-index: 99;
}
.upload-box {
  min-height: 300px;
  max-height: calc(88vh - 250px);
  overflow-y: auto;
  border: 1px solid #ebebeb;
  border-radius: 6px;
  padding: 15px;
  /deep/ {
    .el-upload-list--picture-card .el-upload-list__item {
      width: 100px;
      height: 100px;
      border: none;
      transition: none;
    }
    .el-upload--picture-card {
      width: 100px;
      height: 100px;
      line-height: 100px;
    }
  }
  .item {
    width: 100%;
    height: 100%;
    border-radius: 6px;
    border: 1px solid #c0ccda;
    overflow: hidden;
    cursor: pointer;
    &.checked {
      border: 3px solid #67c23a;
      .actions {
        left: 3px;
        top: 3px;
        width: calc(100% - 6px);
        height: calc(100% - 6px);
      }
    }
  }
  .actions {
    cursor: pointer;
  }
}
.text-selected {
  font-size: 14px;
  color: #606266;
  margin-right: 20px;
}
.footer-box {
  display: flex;
  justify-content: space-between;
  align-items: center;
}
</style>
